﻿#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;

namespace NeoPatterns.Core.Registry.Implementation
{
    /// <summary>
    /// Defines an object
    /// </summary>
    [DebuggerDisplay("ObjectDefinition '{Name}'")]
    internal class ObjectDefinition
    {
        /// <summary>
        /// Object name. Must be globally unique
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Object type.
        /// </summary>
        public Type Type { get; private set; }

        /// <summary>
        /// True if the object is an instance, false if singleton (default = false)
        /// </summary>
        public bool Instance { get; private set; }

        /// <summary>
        /// Create method. Prototype is "object Create(IObjectRegistry objectRegistry)"
        /// If null, default Activator is called
        /// </summary>
        public Delegate Create { get; private set; }

        /// <summary>
        /// Initialize method. Prototype is "void Initialize(object instance, IObjectRegistry objectRegistry)"
        /// If null, no initializer is called
        /// </summary>
        public Delegate Initialize { get; private set; }

        /// <summary>
        /// Explicit aspects related to this type
        /// </summary>
        public IList<Ref> Advisors { get; private set; }

        private static readonly object UnnamedSerialLock = new object();
        private static int UnnamedSerial = 1;
        protected static string GetAnonymousName()
        {
            lock (UnnamedSerialLock)
            {
                var name = string.Format(CultureInfo.InvariantCulture, "${0}", UnnamedSerial);
                ++UnnamedSerial;
                return name;
            }
        }

        public ObjectDefinition(string name, Type type, IList<Ref> advisors, bool instance, Delegate create, Delegate initialize)
        {
            Name = name ?? GetAnonymousName();
            Type = type;
            Instance = instance;
            Create = create;
            Initialize = initialize;
            Advisors = advisors;
        }
    }
}